/**
 * QUANSHI.com Inc.
 * Copyright (c) 2016-2017 All Rights Reserved.
 */
package com.quanshi.scheduler.job.biz.quartz.monitor;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.quanshi.scheduler.core.base.Ret;
import com.quanshi.scheduler.job.biz.quartz.JobDynamicScheduler;
import com.quanshi.scheduler.job.dal.entity.TriggerLog;

/**
 * 
 * @author yanxiang.huang 2017-07-10 16:10:18
 */
public class JobFailMonitor
{

    private static Logger logger = LoggerFactory.getLogger( JobFailMonitor.class );

    private static JobFailMonitor instance = new JobFailMonitor();

    private LinkedBlockingQueue<Long> queue = new LinkedBlockingQueue<Long>( 0xfff8 );

    private Thread monitorThread;

    private boolean toStop = false;

    private JobFailMonitor()
    {
    }

    public static JobFailMonitor getInstance()
    {
        return instance;
    }

    public void start()
    {
        monitorThread = new Thread( new Runnable()
        {

            @Override
            public void run()
            {
                while ( !toStop )
                {
                    try
                    {
                        logger.debug( ">>>>>>>>>>> job monitor beat ... " );
                        Long jobLogId = JobFailMonitor.instance.queue.take();
                        if ( jobLogId != null && jobLogId > 0 )
                        {
                            logger.debug( ">>>>>>>>>>> job monitor heat success, jobLogId:{}.", jobLogId );
                            TriggerLog log = JobDynamicScheduler.triggerLogService.get( jobLogId );
                            if ( log != null )
                            {
                                if ( Ret.SUCCESS_CODE == log.getTriggerCode()
                                        && 0 == log.getHandleCode() )
                                {
                                    logger.debug( "job is running. jobLogId:{}.", jobLogId );
                                    // running
                                    try
                                    {
                                        TimeUnit.SECONDS.sleep( 10 );
                                    }
                                    catch ( InterruptedException e )
                                    {
                                        e.printStackTrace();
                                    }
                                    monitor( jobLogId );
                                }
                                if ( Ret.SUCCESS_CODE == log.getTriggerCode()
                                        && Ret.SUCCESS_CODE == log.getHandleCode() )
                                {
                                    // pass
                                    logger.debug( "fail monitor: job success." );
                                }
                                if ( Ret.FAIL_CODE == log.getTriggerCode()
                                        || Ret.FAIL_CODE == log.getHandleCode())
                                {
                                    // notify owner
                                    logger.debug( "fail monitor: job fail." );
                                }
                            }
                        }
                    }
                    catch ( Exception e )
                    {
                        logger.error( "job monitor error:{}.", e );
                    }
                }
            }
        } );
        monitorThread.setDaemon( true );
        monitorThread.start();
    }

    public void toStop()
    {
        toStop = true;
    }

    public static void monitor( long jobLogId )
    {
        getInstance().queue.offer( jobLogId );
    }
}
